package custcare

import (
	"errors"
	"fmt"
	"wave-admin/global"
	ComReq "wave-admin/model/common/request"
	"wave-admin/model/custcare"
	"wave-admin/model/custcare/request"
	"wave-admin/model/custcare/response"
	"wave-admin/utils"
)

type VisitorService struct{}

func (visitorService *VisitorService) GetVisitorList(info request.VisitorList) (err error, list interface{}, total int64) {
	limit := info.PageSize
	offset := info.PageSize * (info.CurrentPage - 1)
	var visitors []custcare.CusVisitor
	db := global.GnDb.Model(&custcare.CusVisitor{}).Where("status = ?", info.Status).Where("admin_id = ?", 0).Order("id DESC")
	if info.ClientIp != "" {
		db = db.Where("client_ip LIKE ?", "%"+info.ClientIp+"%")
	}
	if info.Provice != "" {
		db = db.Where("provice = ?", info.Provice)
	}
	if info.City != "" {
		db = db.Where("city = ?", info.City)
	}

	err = db.Count(&total).Error
	if err != nil {
		return err, visitors, total
	}

	err = db.Limit(limit).Offset(offset).Find(&visitors).Error

	for i, v := range visitors {
		// 是否在ip黑名单里
		var ipblack custcare.CusIpBlacklist
		global.GnDb.Where("ip = ?", v.ClientIp).First(&ipblack)
		if ipblack.Ip != "" {
			if ipblack.Status == 1 {
				visitors[i].IsIpBlack = 1
			}
		}
	}

	return err, visitors, total
}

func (visitorService *VisitorService) GetVisitor(id int) (err error, visitor custcare.CusVisitor) {
	err = global.GnDb.Model(&custcare.CusVisitor{}).Where("id = ?", id).Find(&visitor).Error
	if err != nil {
		return err, visitor
	}
	visitor.IsIpBlack = 0
	var detail custcare.CusVisitorDetail
	err = global.GnDb.Model(&custcare.CusVisitorDetail{}).Where("visitor_id = ?", id).Find(&detail).Error
	if err != nil {
		return err, visitor
	}
	visitor.Detail = detail

	// 查询是否在ip黑名单里
	var ipblack custcare.CusIpBlacklist
	global.GnDb.Where("ip = ?", visitor.ClientIp).First(&ipblack)
	if ipblack.Ip != "" {
		if ipblack.Status == 1 {
			visitor.IsIpBlack = 1
		}
	}

	return err, visitor
}

func (visitorService *VisitorService) GetTalk(req request.VisitorTalk, userId uint64) (err error, visitor []response.TalkList) {
	var adminVisitor custcare.CusVisitor
	err = global.GnDb.Where("admin_id = ?", userId).First(&adminVisitor).Error
	if err != nil {
		return err, visitor
	}
	err = global.GnDb.Model(&custcare.CusVisitor{}).Select("cus_visitors.id,cus_visitors.uuid,cus_visitors.client_ip,cus_visitors.province,cus_visitors.city,cus_visitors.online,cus_visitor_contacts.status,cus_visitor_contacts.channel_id").Joins("left join cus_visitor_contacts on cus_visitors.id = cus_visitor_contacts.visitor_id").Where("cus_visitor_contacts.has_id = ?", adminVisitor.ID).Where("cus_visitor_contacts.status = ?", 1).Where("cus_visitors.online = ?", req.Online).Order("cus_visitors.id DESC").Scan(&visitor).Error
	//log.Println(visitor)
	if err != nil {
		return err, visitor
	}
	for i, v := range visitor {
		var message custcare.CusMessage
		_err := global.GnDb.Where("channel_id = ?", v.ChannelId).Last(&message).Error
		if _err != nil {
			visitor[i].Msg = "无"
		} else {
			visitor[i].Msg = message.Content
		}
		var unreadCount int64
		global.GnDb.Model(&custcare.CusMessage{}).Where("channel_id = ?", v.ChannelId).Where("visitor_id != ?", adminVisitor.ID).Where("is_read = ?", 0).Count(&unreadCount)
		visitor[i].UnreadCount = unreadCount
	}

	return err, visitor
}

func (visitorService *VisitorService) SetMsgRead(req request.SetMsgRead, userId uint64) (err error) {
	var adminVisitor custcare.CusVisitor
	err = global.GnDb.Where("admin_id = ?", userId).First(&adminVisitor).Error
	if err != nil {
		return err
	}
	update := custcare.CusMessage{
		IsRead: 1,
	}
	err = global.GnDb.Model(&custcare.CusMessage{}).Where("channel_id = ?", req.ChannelId).Where("visitor_id != ?", adminVisitor.ID).Updates(&update).Error

	return err
}

func (visitorService *VisitorService) UpdateVisitorDetail(req request.ReqDetail, visitorId int) (err error) {
	update := custcare.CusVisitorDetail{
		Email:  req.Email,
		Mobile: req.Mobile,
		Name:   req.Name,
		QQ:     req.QQ,
		Wechat: req.Wechat,
		Remark: req.Remark,
	}
	err = global.GnDb.Model(&custcare.CusVisitorDetail{}).Where("visitor_id=?", visitorId).Updates(update).Error

	return err
}

func (visitorService *VisitorService) VisitorIpBlack(req request.VisitorIpBlack) (err error) {
	if req.IsIpBlack == 1 {
		var ipblack custcare.CusIpBlacklist
		global.GnDb.Where("ip = ?", req.Ip).First(&ipblack)
		if ipblack.Ip == "" {
			// 加入黑名单
			add := custcare.CusIpBlacklist{
				Ip: req.Ip,
			}
			err = global.GnDb.Create(&add).Error
		} else {
			// 修改成黑名单
			update := custcare.CusIpBlacklist{
				Status: 1,
			}
			visitorService.DelRedisIpBlack(ipblack.ID)
			err = global.GnDb.Model(&custcare.CusIpBlacklist{}).Where("ip=?", req.Ip).Updates(update).Error
		}
	} else {
		var ipblack custcare.CusIpBlacklist
		global.GnDb.Where("ip = ?", req.Ip).First(&ipblack)
		if ipblack.Ip != "" {
			// 移除黑名单
			update := custcare.CusIpBlacklist{
				Status: 2,
			}
			visitorService.DelRedisIpBlack(ipblack.ID)
			err = global.GnDb.Model(&custcare.CusIpBlacklist{}).Where("ip=?", req.Ip).Updates(update).Error
		}
	}

	return err
}

func (visitorService *VisitorService) DelRedisIpBlack(id uint64) (err error) {
	cacheCusIpBlacklistsIpPrefix := fmt.Sprintf("cache:cusIpBlacklists:id:%d", id)
	//log.Println("IpBlacklists key=", cacheCusIpBlacklistsIpPrefix)
	return global.GnRedis.Del(cacheCusIpBlacklistsIpPrefix).Err()
}

func (visitorService *VisitorService) GetUnreadMsgCount(id uint64) (err error, unread response.UnreadMsg) {
	var visitor custcare.CusVisitor
	err = global.GnDb.Model(&custcare.CusVisitor{}).Where("admin_id = ?", id).Find(&visitor).Error
	if err != nil {
		return err, unread
	}
	var visitorContacts []custcare.CusVisitorContact
	err = global.GnDb.Model(&custcare.CusVisitorContact{}).Where("has_id = ?", visitor.ID).Find(&visitorContacts).Error
	if err != nil {
		return err, unread
	}
	var visitorIds []uint64
	for _, vc := range visitorContacts {
		visitorIds = append(visitorIds, vc.VisitorId)
	}
	where := map[string]interface{}{}
	where["visitor_id"] = visitorIds

	var count int64
	err = global.GnDb.Model(&custcare.CusMessage{}).Where("is_read", 0).Where(where).Count(&count).Error

	unread = response.UnreadMsg{
		Count: count,
	}

	return err, unread
}

func (visitorService *VisitorService) GetTrailList(visitorId int64) (err error, list []response.TrailList) {
	err = global.GnDb.Model(&custcare.CusVisitorContact{}).Select("cus_visitor_contacts.created_at,cus_visitor_contacts.status,cus_visitors.nickname,cus_visitors.avatar,cus_visitor_contacts.channel_id").Joins("left join cus_visitors on cus_visitor_contacts.has_id=cus_visitors.id").Where("cus_visitor_contacts.visitor_id = ?", visitorId).Scan(&list).Error

	return err, list
}

func (visitorService *VisitorService) GetCustcareList(info ComReq.PageInfo, userId uint64) (err error, list interface{}, total int64) {
	limit := info.PageSize
	offset := info.PageSize * (info.CurrentPage - 1)
	var visitors []custcare.CusVisitor
	db := global.GnDb.Model(&custcare.CusVisitor{}).Where("online = ?", 1).Where("admin_id != ?", 0).Where("admin_id != ?", userId).Order("id DESC")

	err = db.Count(&total).Error
	if err != nil {
		return err, visitors, total
	}

	err = db.Limit(limit).Offset(offset).Find(&visitors).Error

	return err, visitors, total
}

func GenChannelIdByContact(userId, hasUserId uint64, secret string) string {
	num := userId + hasUserId
	return genChannelId(fmt.Sprintf("%d%v", num, secret))
}

func genChannelId(key string) string {
	return utils.Md5Encode(key)
}

func (visitorService *VisitorService) TrailNewCustcare(trail request.Trail) (err error, data custcare.CusVisitorContact) {
	var contact custcare.CusVisitorContact
	err = global.GnDb.Model(&custcare.CusVisitorContact{}).Where("channel_id = ?", trail.OldChannelId).First(&contact).Error
	if err != nil {
		return err, data
	}
	if contact.HasId != trail.HasId {
		update := custcare.CusVisitorContact{
			Status: 2,
		}
		err = global.GnDb.Model(&custcare.CusVisitorContact{}).Where("channel_id = ?", trail.OldChannelId).Updates(&update).Error
		if err != nil {
			return err, data
		}

		newContact := custcare.CusVisitorContact{
			VisitorId: contact.VisitorId,
			HasId:     trail.HasId,
			ChannelId: GenChannelIdByContact(contact.VisitorId, trail.HasId, global.GnConfig.JWT.SecretKey),
		}
		err = global.GnDb.Create(&newContact).Error

		return err, newContact
	} else {
		return errors.New("不能选择当前客服"), data
	}
}
